using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Globalization;
using System.Linq;
using System.IO;
using System.Data.Common;
using System.Data.Linq;
using System.Configuration;
using HomeDmsUtils;
using System.Drawing.Printing;
using System.Text.RegularExpressions;
using HomeDMSDomain;
using System.Drawing.Drawing2D;
using System.Data.SqlServerCe;

namespace HomeDms
{
    public partial class DocumentForm : Form
    {

        private BindnFindObjectsDataContext db;
        private Document _doc;
        private bool viewModeIsFilled;
        private bool editModeIsFilled;

        #region Events
        public event EventHandler DocumentCollectionChanged;
        #endregion

        public int DocumentId { get; set; }

        public enum Layouts { View, Edit, New};

        private Layouts layoutMode = Layouts.Edit;

        public Layouts LayoutMode
        {
            get
            {
                return layoutMode;
            }
            set
            {
                layoutMode = value;
                LayoutsTabControl.SelectedIndex = (int)layoutMode;
            }
        }
        
        public DocumentForm()
        {
            InitializeComponent();
        }

        public Document Document
        {
            get
            {
                return _doc;
            }

            set
            {
                _doc = value;
            }
        }

        ScanForm scanForm = null;
        
        private void AcquireButton_Click(object sender, EventArgs e)
        {
            using (scanForm = new ScanForm())
            {
                scanForm.GotImage += new EventHandler(sf_GotImage);
                scanForm.ShowDialog(this);
            }
        }

        void sf_GotImage(object sender, EventArgs e)
        {
            AddPage(scanForm.ScannedImage);
            Repaginate();
            modified = true;
        }

        private void AddPage(Image image, string name)
        {
            PageControl page = new PageControl(name, image);
            page.Changed += new EventHandler(page_Changed);
            pagesFlowLayoutPanel.Controls.Add(page);
        }

        void page_Changed(object sender, EventArgs e)
        {
            Repaginate();
        }

        private void Repaginate()
        {
            foreach (PageControl pc in pagesFlowLayoutPanel.Controls)
            {
                int idx = pagesFlowLayoutPanel.Controls.GetChildIndex(pc);
                pc.PageOrder = idx;
                Regex expr = new Regex(@"Page \d");
                if (expr.IsMatch(pc.Text) || string.IsNullOrEmpty(pc.Text))
                {
                    pc.DefaultPageName = "Page " + (idx + 1).ToString();
                }
                    //pc.DefaultPageName = "Page " + (idx + 1).ToString();
            }
            modified = true;
        }

        private void AddPage(Image image)
        {
            AddPage(image, string.Empty);
            Repaginate();
        }

        public event EventHandler DocumentsUpdated;

        private void NewDocumentForm_Load(object sender, EventArgs e)
        {
            Cursor = Cursors.WaitCursor;
            try
            {
                db = BindnFindObjectsDataContext.Instance;

                if (DocumentId != 0)
                {
                    try
                    {
                        _doc = db.Documents.Single<Document>(d => d.document_id == DocumentId);
                    }
                    catch (InvalidOperationException)
                    {
                       Localizer.MsgBox(this, "Document was not found", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }

                switch (this.LayoutMode)
                {
                    case Layouts.View:
                        FillViewControls();
                        break;
                    case Layouts.Edit:
                        FillEditValues();
                        break;
                    case Layouts.New:
                        FillDefaultValues();
                        break;
                }
            }
            finally
            {
                Cursor = Cursors.Default;
            }
        }

        private void FillEditValues()
        {
            if (db.Documents.Count<Document>() >= 5000)
            {
                SaveAndNewButton.Enabled = false;
            }
            else
            {
                SaveAndNewButton.Enabled = true;
            }

            FillDefaultValues();
            if (_doc != null)
            {
                if (_doc.Pages.Count >= 40)
                {
                    scanButton.Enabled = false;
                    addNewFileButton.Enabled = false;
                }
                else
                {
                    scanButton.Enabled = true;
                    addNewFileButton.Enabled = true;
                }
                pictureBox1.Image = Properties.Resources.Scanner_Check;
                FillDocumentValues();
            }
            UpdateControls();
            editModeIsFilled = true;
            NameTextBox.Focus();
        }

        private void FillViewControls()
        {
            if (_doc == null)
                return;
            if (_doc.EnteredOn.HasValue)
            {
                txtAddDate.Text = _doc.EnteredOn.Value.ToString("yyyy-MMM-dd H:mm:ss");
            }

            txtViewDocumentName.Text = _doc.Name;
            txtViewDocumentDescription.Text = _doc.Description;
            var q = from dt in _doc.Document_Tags select dt.Tag;
            lstViewTagsBox.Items.AddRange(new List<Tag>(q).ToArray<Tag>());
            try
            {
                PagesSource.DataSource = _doc.Pages.ToList<Page>();
            }
            catch (SqlCeException ex)
            {
                if (ex.Message.IndexOf("File") > 0 || ex.Message.IndexOf("Thumbnail") > 0)
                {
                    MessageBox.Show(this, "Old version of DB file detected we try convert this", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    DBConverter.ConvertDBToFileVersion((SqlCeConnection)db.Connection);
                    PagesSource.DataSource = _doc.Pages.ToList<Page>();
                }
                else
                {
                    throw;
                }
                
            } 
            viewModeIsFilled = true;
        }

        private void SetCulture(CultureInfo culture)
        {
            for (int i = 0; i < comboBox1.Items.Count; i++)
            {
                CultureInfo item = comboBox1.Items[i] as CultureInfo;
                if (item != null && item.Equals(culture))
                {
                    comboBox1.SelectedIndex = i;
                    return;
                }
            }
        }

        private void FillDocumentValues()
        {
            // attach _doc to _session
            NameTextBox.Text = _doc.Name;
            txtDescription.Text = _doc.Description;

            if (_doc.LCID != 0)
            {
                CultureInfo culture = new CultureInfo(_doc.LCID);
                SetCulture(culture);
            }

            if (_doc.From.HasValue && _doc.To.HasValue)
            {
                HasPeriodCheckBox.Checked = true;
                fromDatePicker.Value = _doc.From.Value;
                toDatePicker.Value = _doc.To.Value;
            }

            var qu = from dt in _doc.Document_Tags select dt.Tag;
            DocTagListBox.Items.AddRange(new List<Tag>(qu).ToArray<Tag>());
            
            var q = from p in _doc.Pages orderby p.Order select p;
            foreach (Page page in q)
            {
                PageControl pageCtl = new PageControl(page);
                pagesFlowLayoutPanel.Controls.Add(pageCtl);
            }
        }        

        private void FillDefaultValues()
        {
            var q = from cult in CultureInfo.GetCultures(CultureTypes.AllCultures)
                    orderby cult.DisplayName
                    select cult;
            comboBox1.Items.Clear();
            comboBox1.Items.AddRange(q.ToArray<CultureInfo>());
            DocTagListBox.Items.Clear();

            FillTagsListBox(db.Tags.ToList<Tag>());
            
            //List<string> l = _session.CreateQuery("select doc.Name from Document doc").List<string>() as List<string>;
            var query = from doc in db.Documents select doc.Name;            
            AutoCompleteStringCollection autoc = new AutoCompleteStringCollection();
            autoc.AddRange(query.ToList<string>().ToArray());
            NameTextBox.AutoCompleteCustomSource = autoc;
            NameTextBox.Focus();
        }

        private void FillTagsListBox(List<Tag> list)
        {
            AllTagListBox.Items.Clear();
            AllTagListBox.Items.AddRange(list.ToArray<Tag>());
        }

        private void AddTagButton_Click(object sender, EventArgs e)
        {
            AddNewTagForm dialog = new AddNewTagForm();
            dialog.PlaningTagName = textBox2.Text;
            DialogResult res = dialog.ShowDialog(this);
            if (res == DialogResult.OK)
            {
                db.Tags.InsertOnSubmit(new Tag { Name = dialog.ReturnName });
                db.SubmitChanges();
            }
            FillTagsListBox(db.Tags.ToList<Tag>());
        }

        private void DeleteTagButton_Click(object sender, EventArgs e)
        {            
            Tag tag = AllTagListBox.SelectedItem as Tag;

            if (tag == null)
            {
                Localizer.MsgBox(this, "Please select tag to delete", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            int count = db.Document_Tags.Count<Document_Tag>(dt => dt.tag_id == tag.tag_id);
            if (count > 0)
            {
                if (Localizer.MsgBox(this, "You are trying to delete tag which is in use by {0} document(s). Are you sure you want to delete it anyway?",
                    "Delete tag", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning, count) != DialogResult.Yes)
                    return;
            }
            if (tag == null)
            {
                return;
            }
            try
            {
                db.Tags.DeleteOnSubmit(tag);
                var qt = from dt in db.Document_Tags where dt.tag_id == tag.tag_id select dt;
                db.Document_Tags.DeleteAllOnSubmit<Document_Tag>(qt);

                db.SubmitChanges();
                FillTagsListBox(db.Tags.ToList<Tag>());
            }
            catch (Exception ex)
            {
                Localizer.MsgBox(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }            
        }

        private void AddFiles_Click(object sender, EventArgs e)
        {
            openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
            DialogResult res = openFileDialog.ShowDialog(this);
            if (res == DialogResult.OK)
            {
                InsertFiles(openFileDialog.FileNames);
            }
        }

        private void InsertFiles(string[] fileNames)
        {
            foreach (string file in fileNames)
            {       
                string ext = Path.GetExtension(file).ToLower();
                if (ext == ".jpg" || ext == ".jpeg" || ext == ".gif" ||
                    ext == ".tif" || ext == ".tiff" || ext == ".bmp" || ext == ".png")
                {
                    Image img = null;
                    try
                    {
                        img = Bitmap.FromFile(file);
                    }
                    catch
                    {
                        continue;
                    }
                    FileInfo fi = new FileInfo(file);
                    AddPage(img, fi.Name);
                    Repaginate();
                }
                else
                {
                }
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            for (int i = pagesFlowLayoutPanel.Controls.Count - 1; i > -1; i--)
            {
                PageControl p = pagesFlowLayoutPanel.Controls[i] as PageControl;
                if (p.PageSelected)
                {
                    if (_doc != null && p.Page != null && _doc.Pages.Contains(p.Page))
                    {
                        
                        _doc.Pages.Remove(p.Page);
                        db.Pages.DeleteOnSubmit(p.Page); 
                    }
                    pagesFlowLayoutPanel.Controls.Remove(p);
                    p.Dispose();
                }
            }
        }

        private void NewDocumentForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            PageControl.pageZoomForm = null;
        }

        private void SaveAndCloseButton_Click(object sender, EventArgs e)
        {
            if (!SaveDocument())
                return;
            DialogResult = DialogResult.OK;
            modified = false;
            Close();
        }

        /// <summary>
        /// First function if form saving all in the DB
        /// </summary>
        /// <returns></returns>
        private bool SaveDocument()
        {
            if (string.IsNullOrEmpty(NameTextBox.Text))
            {
                Localizer.MsgBox(this, "Please enter document name", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                NameTextBox.Focus();
                return false;
            }


            try
            {
                if (_doc == null)
                {
                    _doc = new Document();
                    _doc.EnteredOn = DateTime.Now;
                    db.Documents.InsertOnSubmit(_doc);
                }


                _doc.Name = NameTextBox.Text;
                _doc.Description = txtDescription.Text;
                if (comboBox1.SelectedIndex >= 0)
                {
                    CultureInfo culture = comboBox1.SelectedItem as CultureInfo;
                    if (culture != null)
                    {
                        _doc.LCID = culture.LCID;
                    }
                }

                if (HasPeriodCheckBox.Checked)
                {
                    _doc.From = fromDatePicker.Value;
                    _doc.To = toDatePicker.Value;
                }
                else
                {
                    _doc.From = null;
                    _doc.To = null;
                }


                foreach (PageControl pc in pagesFlowLayoutPanel.Controls)
                {
                    if (!_doc.Pages.Contains(pc.Page))
                    {
                        pc.Page.Document = _doc;
                        _doc.Pages.Add(pc.Page);
                        db.Pages.InsertOnSubmit(pc.Page);
                    }
                }

                if (_doc.Document_Tags.Count > 0)
                {
                    var q = from dt in db.Document_Tags where dt.document_id == _doc.document_id select dt;
                    db.Document_Tags.DeleteAllOnSubmit<Document_Tag>(q);
                    db.SubmitChanges();
                }

                foreach (Tag item in DocTagListBox.Items)
                {
                    Document_Tag dt = new Document_Tag { Document = _doc, Tag = item };
                    db.Document_Tags.InsertOnSubmit(dt);
                }
                db.SubmitChanges();
                if (DocumentCollectionChanged != null)
                {
                    DocumentCollectionChanged(this, new EventArgs());
                }
            }
            catch (SqlCeException ceEx)
            {
                if (ceEx.Message.IndexOf("File") > 0 || ceEx.Message.IndexOf("Thumbnail") > 0)
                {
                    MessageBox.Show(this, "Old version of DB detected we try fix the DB file.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    DBConverter.ConvertDBToFileVersion((SqlCeConnection)db.Connection);
                    db.SubmitChanges();
                    return true;
                }
                throw;
            }
            catch (Exception ex)
            {
                Localizer.MsgBox(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return false;
            }
            return true;
        }

        private void NotifyDocumentsUpdated()
        {
            if (DocumentsUpdated != null)
                DocumentsUpdated(this, EventArgs.Empty);
        }

        private bool modified = false;

        private void NameTextBox_TextChanged(object sender, EventArgs e)
        {
            this.Text = string.Format("Document - {0}", NameTextBox.Text);
            modified = true;
        }

        private void EditPage_Click(object sender, EventArgs e)
        {
            foreach (PageControl p in pagesFlowLayoutPanel.Controls)
            {
                if (p.PageSelected)
                {
                    p.Edit();
                    break;
                }
            }
        }

        private void SaveAndNewButton_Click(object sender, EventArgs e)
        {
            if (SaveDocument())
            {
                ClearDocument();
            }
        }

        private void ClearDocument()
        {
            NameTextBox.Clear();
            txtDescription.Clear();
            pagesFlowLayoutPanel.Controls.Clear();
            db = BindnFindObjectsDataContext.Instance;
            _doc = null;
            FillDefaultValues();
        }

        private void textBox2_TextChanged(object sender, EventArgs e)
        {
            FilterTags();
        }

        private void FilterTags()
        {
            AllTagListBox.Items.Clear();
            var filteredTags = from filteredTag in db.Tags
                               where filteredTag.Name.Contains(textBox2.Text)
                               select filteredTag;
            AllTagListBox.Items.Clear();
            AllTagListBox.Items.AddRange(filteredTags.ToArray<Tag>());
            UpdateControls();

        }

        private void UpdateControls()
        {
            AddTagButton.Enabled = AllTagListBox.Items.Count == 0 && textBox2.Text != "";
            DeleteTagButton.Enabled = AllTagListBox.SelectedIndex >= 0;
            AddTagIntoDocButton.Enabled = AllTagListBox.SelectedIndex >= 0;
            DropTagFromDocButton.Enabled = DocTagListBox.SelectedIndex >= 0;
            fromDatePicker.Enabled = HasPeriodCheckBox.Checked;
            toDatePicker.Enabled = HasPeriodCheckBox.Checked;
            label4.Enabled = HasPeriodCheckBox.Checked;
            label5.Enabled = HasPeriodCheckBox.Checked;
        }

        private void AllTagListBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            UpdateControls();
        }

        private void AddTagIntoDocButton_Click(object sender, EventArgs e)
        {
            foreach (Tag tag in AllTagListBox.SelectedItems)
            {
                if (!DocTagListBox.Items.Contains(tag))
                    DocTagListBox.Items.Add(tag);
            }
        }

        private void DocTagListBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            UpdateControls();
            modified = true;
        }

        private void DropTagFromDocButton_Click(object sender, EventArgs e)
        {
            List<Tag> toRemove = new List<Tag>();            
            foreach (Tag tag in DocTagListBox.SelectedItems)
            {
                toRemove.Add(tag);
            }
            foreach (Tag tag in toRemove)
            {
                DocTagListBox.Items.Remove(tag);
            }
        }

        private void HasPeriodCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            UpdateControls();
            modified = true;
        }

        private void UpPageButton_Click(object sender, EventArgs e)
        {            
            List<PageControl> toMove = new List<PageControl>();
            foreach (PageControl pc in pagesFlowLayoutPanel.Controls)
                if (pc.PageSelected)
                    toMove.Add(pc);
            foreach (PageControl pc in toMove)
            {
                int idx = pagesFlowLayoutPanel.Controls.GetChildIndex(pc);
                if (idx != 0)
                {
                    pagesFlowLayoutPanel.Controls.SetChildIndex(pc, idx - 1);
                    pagesFlowLayoutPanel.ScrollControlIntoView(pc);
                }
            }
            Repaginate();
        }

        private void DownPageButton_Click(object sender, EventArgs e)
        {
            List<PageControl> toMove = new List<PageControl>();
            foreach (PageControl pc in pagesFlowLayoutPanel.Controls)
                if (pc.PageSelected)
                    toMove.Add(pc);
            foreach (PageControl pc in toMove)
            {
                int idx = pagesFlowLayoutPanel.Controls.GetChildIndex(pc);
                if (idx != pagesFlowLayoutPanel.Controls.Count - 1)
                {
                    pagesFlowLayoutPanel.Controls.SetChildIndex(pc, idx + 1);
                    pagesFlowLayoutPanel.ScrollControlIntoView(pc);
                }
            }
            Repaginate();
        }

        private void tabPage1_Click(object sender, EventArgs e)
        {

        }

        private void pagesFlowLayoutPanel_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
                e.Effect = DragDropEffects.All;
        }

        private void pagesFlowLayoutPanel_DragDrop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                string[] files;
                files = e.Data.GetData(DataFormats.FileDrop) as string[];
                InsertFiles(files);
            }
        }

        private void PagesSource_PositionChanged(object sender, EventArgs e)
        {
            int position;
            if (int.TryParse(PagesNavigator.PositionItem.Text, out position))
            {
                pagesViewControl.Image = _doc.Pages[position - 1].Image;
                txtViewPageName.Text = _doc.Pages[position - 1].Name;
            }
        }

        private void LayoutsTabControl_SelectedIndexChanged(object sender, EventArgs e)
        {
            TabControl tabs = sender as TabControl;
            switch (tabs.SelectedIndex)
            {
                case 0:
                    if (!viewModeIsFilled)
                    {
                        FillViewControls();
                    }
                    break;
                case 1:
                    if (!editModeIsFilled)
                    {
                        FillEditValues();
                    }
                    break;
            }
        }

        #region Printing

        private bool printTitlePage;
        private bool printCurrentPageOnly;

        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            if (_doc == null)
                return;
            using (PrePrintForm ppf = new PrePrintForm())
            {
                ppf.PrintDocument = printDocument1;
                if (ppf.ShowDialog(this) == DialogResult.OK)
                {
                    printTitlePage = ppf.printInfoCheckBox.Checked;
                    printCurrentPageOnly = ppf.printCurrentRadioButton.Checked; 
                    printDocument1.Print();
                }
            }
        }

        private int printingPageNo = 0;
        private Page printingPage = null;
        private bool titlePagePrinted = false;

        private void printDocument1_BeginPrint(object sender, System.Drawing.Printing.PrintEventArgs e)
        {            
            printingPageNo = 0;
            titlePagePrinted = !printTitlePage;
            if (printCurrentPageOnly)
                printingPage = PagesSource.Current as Page;
            else
                if (_doc.Pages.Count > 0)
                    printingPage = PagesSource.List[printingPageNo] as Page;
                else
                    printingPage = null;
        }

        private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
        {
            // Always print logo on each page
            PrintLogo(e);

            // If asked print title page (general document info page)
            if (!titlePagePrinted)
            {
                PrintTitlePage(e);
                titlePagePrinted = true;
                e.HasMorePages = HasMorePages();
                return;
            }
            
            // If asked print just one current page
            if (printCurrentPageOnly)
            {
                PrintPage(e, printingPage.Image);
                PrintPageName(e);
                e.HasMorePages = false;
                return;
            } 
            
            // Regular print page
            PrintPage(e, printingPage.Image);
            PrintPageName(e);
            printingPageNo++;
            e.HasMorePages = HasMorePages();
            if (e.HasMorePages)
                printingPage = PagesSource.List[printingPageNo] as Page;
        }

        private bool HasMorePages()
        {
            return printingPageNo <= PagesSource.Count - 1;
        }

        private void PrintPageName(System.Drawing.Printing.PrintPageEventArgs e)
        {
            string text = Localizer.GetStr("Page: {0} ({1} of {2})", printingPage.Name, printingPageNo + 1, _doc.Pages.Count); 
            e.Graphics.DrawString(text, new Font("Tahoma", 12), Brushes.Black, e.PageBounds.X + 30, e.PageBounds.Bottom - (e.PageBounds.Bottom - e.MarginBounds.Bottom) / 2); 
        }

        private void PrintTitlePage(System.Drawing.Printing.PrintPageEventArgs e)
        {
            string docTitle = Localizer.GetStr("Document: {0}", _doc.Name);
            e.Graphics.DrawString(docTitle, new Font("Tahoma", 14, FontStyle.Bold), Brushes.Black, e.MarginBounds.X, e.MarginBounds.Y + 20);
            string text = Localizer.GetStr(@"
(added: {0})

Printing {1} page(s); document has {2} page(s).

Description:
{3}

Tags:
{4}", 
            _doc.EnteredOn.GetValueOrDefault(), 
            printCurrentPageOnly ?  1 : _doc.Pages.Count,
            _doc.Pages.Count, 
            string.IsNullOrEmpty(_doc.Description) ? "<none>" : _doc.Description,
            string.IsNullOrEmpty(_doc.Keywords) ? "<none>" : _doc.Keywords);

            e.Graphics.DrawString(text, new Font("Tahoma", 12), Brushes.Black, e.MarginBounds.X, e.MarginBounds.Y + 40);            
        }

        private void PrintPage(PrintPageEventArgs e,Image image)
        {
            PrintImage(e.Graphics, e.MarginBounds, image);            
        }

        private void PrintImage(Graphics g, Rectangle bounds, Image image)
        {
            Size zsize = image.GetZoomedSizeForPrinter(bounds.Size, g.DpiX, g.DpiY);
            Rectangle destRect = new Rectangle(bounds.X, bounds.Y, zsize.Width, zsize.Height);
            g.CompositingQuality = CompositingQuality.HighQuality;
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.DrawImage(image, destRect);
            //g.DrawRectangle(Pens.Black, destRect);
        }

        private void PrintLogo(PrintPageEventArgs e)
        {
            Image img = Properties.Resources.logo;
            Rectangle rect = new Rectangle(e.PageBounds.X + 20, e.PageBounds.Y + 20, 
                e.PageBounds.Width, e.MarginBounds.Top - e.PageBounds.Top - 50);
            PrintImage(e.Graphics, rect, img);
            e.Graphics.DrawString("Bind`n`find 1.0", new Font("Tahoma", 10), Brushes.Gray, 
                e.PageBounds.X + 140, e.PageBounds.Y + 20);
            e.Graphics.DrawString("www.bind-n-find.com", new Font("Tahoma", 8), Brushes.DarkGreen,
                e.PageBounds.X + 140, e.PageBounds.Y + 40);
        }

        private void toolStripButton2_Click(object sender, EventArgs e)
        {
            if (_doc == null)
                return;
            printPreviewDialog1.Top = 50;
            printPreviewDialog1.Left = 50;
            printPreviewDialog1.Width = 600;
            printPreviewDialog1.Height = 800;
            bool save = printTitlePage;
            printTitlePage = true;
            printPreviewDialog1.ShowDialog(this);
            printTitlePage = save;
        }

        #endregion

        #region Services (PDF, email etc.)

        private void createPdfToolStripButton_Click(object sender, EventArgs e)
        {
            if (_doc == null)
                return;
            if (saveFileDialog1.ShowDialog(this) != DialogResult.OK)
                return;
            CreatePDF(saveFileDialog1.FileName);
            process1.StartInfo.FileName = saveFileDialog1.FileName;
            process1.Start();           
        }

        private void CreatePDF(string fileName)
        {
            pdfPrinter1.Author = "Zoo# Technologies";
            pdfPrinter1.Document = printDocument1;
            pdfPrinter1.FileName = fileName;
            pdfPrinter1.Title = _doc.Name;            
            printTitlePage = false;
            try
            {
                pdfPrinter1.Print();
            }
            catch (Exception ex)
            {
                Localizer.MsgBox(this, "Error occured while creating PDF file: {0}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error, ex.Message);
            }
        }

        private void sendByEMailToolStripButton_Click(object sender, EventArgs e)
        {
            if (_doc == null)
                return;
            using (MailMessageForm mmf = new MailMessageForm())
            {
                mmf.attached.Text = _doc.Name;
                if (mmf.ShowDialog(this) != DialogResult.OK)
                    return;
                mmf.message.Text += @"
---
This message was sent to you with Bind`n`find software - the best way to scan, store and organize your documents.
Download today your free copy from Zoo# Technologies website at http://bind-n-find.com.";
                try
                {             
                    string tempDirName = Path.Combine(Path.GetTempPath(), "Bind`n`find");
                    DirectoryInfo tempDir = Directory.CreateDirectory(tempDirName);
                    string tempFileName = Path.Combine(tempDir.FullName, "Document.pdf");
                    File.Delete(tempFileName);
                    CreatePDF(tempFileName);
                    SendFileTo.MAPI mapi = new SendFileTo.MAPI();
                    mapi.AddAttachment(tempFileName);          
                    string[] emails = mmf.addressBox.Text.Split(';');
                    foreach (string email in emails)
                        mapi.AddRecipientTo(email);
                    mapi.SendMailDirect(mmf.subject.Text, mmf.message.Text);
                }
                catch (Exception ex)
                {
                    Localizer.MsgBox(this, ex.Message, "Simple MAPI Error",
                        MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private void exportCurrentPageToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (_doc == null)
                return;
            if (saveFileDialog2.ShowDialog(this) != DialogResult.OK)
                return;
            int position;
            if (int.TryParse(PagesNavigator.PositionItem.Text, out position))
                _doc.Pages[position - 1].Image.Save(saveFileDialog2.FileName, System.Drawing.Imaging.ImageFormat.Jpeg);
            else
                Localizer.MsgBox(this, "Cannot read position of page", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }

        private void exportAllPagesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (_doc == null)
                return;
            if (folderBrowserDialog1.ShowDialog(this) != DialogResult.OK)
                return;
            string filePath = folderBrowserDialog1.SelectedPath;
            string baseName = Path.Combine(filePath, Path.GetFileNameWithoutExtension(filePath));
            int index = 1;
            foreach (Page p in _doc.Pages)
            {
                p.Image.Save(baseName + ".page_" + index.ToString() + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
                index++;
            }
        }

        #endregion

        private void toolStripButton3_Click(object sender, EventArgs e)
        {

        }

        private void txtDescription_TextChanged(object sender, EventArgs e)
        {
            modified = true;
        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            modified = true;
        }

        private void fromDatePicker_ValueChanged(object sender, EventArgs e)
        {
            modified = true;
        }

        private void toDatePicker_ValueChanged(object sender, EventArgs e)
        {
            modified = true;
        }

        private void DocumentForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (modified)
            {
                DialogResult res = Localizer.MsgBox(this, "Document was modified. Do you want to save changes?", "Save document",
                    MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);
                switch (res)
                {
                    case DialogResult.Cancel:
                        e.Cancel = true;
                        break;
                    case DialogResult.Yes:
                        SaveAndCloseButton_Click(sender, EventArgs.Empty);
                        break;
                }
            }
        }

        private void DocumentForm_Shown(object sender, EventArgs e)
        {
            modified = false;
        }

    }

}

